﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Server;
using ESRI.ArcGIS.Framework;
using mapXBase;
using mc_basXcls7Lib;
using mc_basObj7Lib;
using System.Collections;
using mx_MapLibCtrlLib;
using System.IO;
using System.Threading;

namespace ConvertProject
    
{
    /************************************************************************/
    /* 区转换                                                               */
    /************************************************************************/
    class RegConvert
    {
        //收集已经使用过的子图
        StyleSymbolMap mStyleSymbolMap = null;

        //public List<IStyleGalleryItem> list = new List<IStyleGalleryItem>();

        public void SetStyleSymbolMap(StyleSymbolMap styleSymbolMap)
        {
            mStyleSymbolMap = styleSymbolMap;
        }

        public void readWP(IXGroupLayer grouplayer, string groupname, IMap imap, string savepath, IMapDocument m_MapDocument, string stylepath,  int GCScode)
        {
            IXMapLayer wplayer = grouplayer.get_Layer(1);

            string layername = groupname.Substring(0, groupname.Length - 3);
            layername = layername + "_Reg";
            //Logfile.WriteLogFile(layername);
            
            //获取图层简答要素类
            mcSFeatureCls m_sfcls = wplayer.XClass as mcSFeatureCls;

            //查询属性记录  区的总个数 以及objectid
            mcRecordSet recordset = null;
            m_sfcls.Select(null, out recordset);
            if (recordset == null)
            {
                return;
            }
            recordset.MoveFirst();

            //获取区属性列名
            mcFields attfields;
            recordset.GetFields(out attfields);
            string[] attname = new string[attfields.numbfield];
            for (short i = 0; i < attfields.numbfield; i++)
            {
                attname[i] = attfields.get_fldEntry(i).fieldname;
            }

            IGeomInfo info = null;
            mc_basObj7Lib.IGeometry itry = null;
            mcRecord record = null;
            mcObjectID id = new mcObjectID();

            /************************************************************************/
            /* 生成shapefile文件                                                    */

            //const string strFolder = @"D:\MXD1"; 　　//目标文件夹
            string strName = layername;　　//文件名
            const string strShapeFieldName = "Shape";

            //Open the folder to contain the shapefile as a workspace
            IFeatureWorkspace pFWS;
            IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
            pFWS = pWorkspaceFactory.OpenFromFile(savepath, 0) as IFeatureWorkspace;

            //Set up a simple fields collection
            ESRI.ArcGIS.Geodatabase.IFields pFields = new FieldsClass();　　//字段
            IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;

            //Make the shape field
            //it will need a geometry definition, with a spatial reference
            ESRI.ArcGIS.Geodatabase.IField pField = new FieldClass();
            IFieldEdit pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Name_2 = strShapeFieldName;
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

            IGeometryDef pGeometryDef = new GeometryDef();
            IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
            pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon; //设置shp为区类型*************

            //************设置坐标系 *********
            ISpatialReferenceFactory2 ipSpaRefFact2 = new SpatialReferenceEnvironmentClass();
            IGeographicCoordinateSystem ipGeoCoordSys = new GeographicCoordinateSystemClass();
            if (GCScode != 0)
            {
                ipGeoCoordSys = ipSpaRefFact2.CreateGeographicCoordinateSystem(GCScode);
                pGeometryDefEdit.SpatialReference_2 = ipGeoCoordSys as ISpatialReference;
            }
            else
            {
                pGeometryDefEdit.SpatialReference_2 = new UnknownCoordinateSystem() as ISpatialReference;
            }
            //************设置坐标系 *********

            pFieldEdit.GeometryDef_2 = pGeometryDef;
            pFieldsEdit.AddField(pField);


            //添加字段        
            mcFields fields;
            recordset.GetFields(out fields);
            short numfields = fields.numbfield;
            for (short i = 0; i < numfields; i++)
            {
                mcField field = fields.get_fldEntry(i);
                pField = new FieldClass();
                pFieldEdit = pField as IFieldEdit;
                pFieldEdit.Length_2 = 15;
                pFieldEdit.Name_2 = attname[i];
                pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
                pFieldsEdit.AddField(pField);
            }

            //Add fillmode field   填充模式
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "fillmode";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            //Add patid field 填充图案号
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "patid";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add fillcolor field 区填充色
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "fillcolor";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add width field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "width";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;
            pFieldsEdit.AddField(pField);

            //Add height field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "height";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;
            pFieldsEdit.AddField(pField);

            //Add patcolor field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "patcolor";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);


            //Add OID field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            //pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "IDS";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            /**额外添加字段**/
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 150;
            pFieldEdit.Name_2 = "GEONAME";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 60;
            pFieldEdit.Name_2 = "SIPNAME";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "GEOCODE";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 8;
            pFieldEdit.Name_2 = "GEOOBJNUM";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 20;
            pFieldEdit.Name_2 = "SHOWLEVEL";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            /**额外添加字段**/

            //Create the shapefile
            IFeatureClass featureClass = pFWS.CreateFeatureClass(strName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
            //MessageBox.Show(featureClass.ShapeType.ToString());
            //featureClass.ShapeType = esriGeometryType.esriGeometryLine;

            /************************************************************************************************************************/

            for (int j = 0; j < recordset.count; j++)
            {
                /*********************向shapefile文件插入记录***********************/
                IFeatureCursor pInsertFeatureCursor;
                pInsertFeatureCursor = featureClass.Insert(true);

                IFeatureBuffer pInsertFeatureBuffer;
                pInsertFeatureBuffer = featureClass.CreateFeatureBuffer();

                /*********************向shapefile文件插入记录***********************/

                //获取对象的id号   OID
                recordset.GetID(out id);
                recordset.MoveNext();
                //MessageBox.Show(id.Int+":OID");
                //Logfile.WriteLogFile(id.String + ":OID");
                //int aaa = featureClass.FindField("AAA");
                //MessageBox.Show(aaa + "");
                pInsertFeatureBuffer.set_Value(featureClass.FindField("IDS"), id.String);

                //获取线文件的属性，图形参数和线对应的坐标。
                m_sfcls.Get(id, out itry, out record, out info);


                //区的图形参数
                IRegInfo reginfo = (IRegInfo)info;
                pInsertFeatureBuffer.set_Value(featureClass.FindField("fillmode"), reginfo.fillmode);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("fillcolor"), reginfo.fillclr);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("patid"), reginfo.patID);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("patcolor"), reginfo.patclr);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("height"), reginfo.pathei);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("width"), reginfo.patwid);

                //区上的线信息 以及线上的点坐标

                ILine iline;
                IPoint ipointfrom;
                IPoint ipointto;

                ISegment isegment;
                ISegmentCollection pRing = new RingClass();
                IGeometryCollection pPolygon = new PolygonClass();

                IGeoPolygon lintry = (IGeoPolygon)itry;
                int circlenum = lintry.GetCircleNum();  //区上的圈数
                //MessageBox.Show("圈的数量为：" + circlenum);
                for (int i = 0; i < circlenum; i++)
                {

                    //获取区上每条线的坐标         
                    mcDots dots = null;
                    lintry.GetDots(i, out dots);
                    double x, y;
                    //MessageBox.Show(dots.count + "");

                    //区内部的线正反向已经符合区的正反向要求。
                    for (int k = 0; k < dots.count - 1; k++)
                    {
                        ipointfrom = new ESRI.ArcGIS.Geometry.Point();
                        ipointto = new ESRI.ArcGIS.Geometry.Point();

                        dots.Get(k, out x, out y);
                        ipointfrom.X = x;
                        ipointfrom.Y = y;

                        dots.Get(k + 1, out x, out y);
                        ipointto.X = x;
                        ipointto.Y = y;

                        iline = new ESRI.ArcGIS.Geometry.Line();
                        iline.PutCoords(ipointfrom, ipointto);

                        isegment = (ISegment)iline;
                        pRing.AddSegment(isegment);
                    }
                  
                    //分割区中的多条线
                    pPolygon.AddGeometry((ESRI.ArcGIS.Geometry.IGeometry)pRing);
                    pRing = new RingClass();
                }
                pInsertFeatureBuffer.Shape = (ESRI.ArcGIS.Geometry.IGeometry)pPolygon;

                //区的属性信息
                mcFields fields1;
                record.GetFields(out fields1);
                //区上各属性字段对应的值
                for (int i = 0; i < fields1.numbfield; i++)
                {
                    mcField field = fields.get_fldEntry((short)i);
                    string strout;                 //属性字段值
                    meFieldType metype;           //属性字段类型
                    short isnull;              //字段是否为空
                    record.CvtFldToString(attname[i], out strout, out metype, out isnull);

                    //if (attname[i].Equals("ID") || attname[i].Equals("mpLayer"))
                    //{
                        //pInsertFeatureBuffer.set_Value(featureClass.FindField(attname[i]), strout);
                        pInsertFeatureBuffer.set_Value(i+2, strout);
                    //}
                    
                    //  strout 为字段值  name  为字段名
                    //MessageBox.Show(name+"/"+strout);
                }
                /*********************向shapefile文件插入记录***********************/
                //MessageBox.Show(featureClass.FindField("SubNo") + "");

                //InsertFeature
                pInsertFeatureCursor.InsertFeature(pInsertFeatureBuffer);
                pInsertFeatureCursor.Flush();
                /*********************向shapefile文件插入记录***********************/
            }

            //向MXD中添加图层
            IFeatureLayer pFeatureLayer = new FeatureLayerClass();
            pFeatureLayer.FeatureClass = featureClass;
            pFeatureLayer.Name = strName;
            ILayer ilayer =(ILayer)pFeatureLayer;
            //ilayer.Visible = true;
            
            imap.AddLayer(ilayer);

            //渲染图层
            RegRender(savepath, strName, featureClass,ilayer,stylepath);

            //m_MapDocument.Save();
            //System.GC.Collect();
            //WriteLogFile("结束");
        }

        //区渲染
        private void RegRender(string savepath, string strName, IFeatureClass featureClass, ILayer ilayer, string stylepath)
        {
            //生成lyr文件
            ILayerFile layerfile = new LayerFileClass();
            string filename = savepath + "\\" + strName + ".lyr";
            layerfile.New(filename);

            //生成渲染对象
            IUniqueValueRenderer render = new UniqueValueRendererClass();
            IQueryFilter queryfileter = new QueryFilterClass();
            IFeatureCursor featurecursor = featureClass.Search(queryfileter, false);

            //创建简单填充
            IFillSymbol fillsymbol = new SimpleFillSymbolClass();
            IFillSymbol simpleFillsymbol = new SimpleFillSymbolClass();
            //ISimpleFillSymbol simpleFillsymbol = new SimpleFillSymbolClass();//单一色填充
            //渲染字段设置
            string fillname = "IDS";
            render.FieldCount = 1;
            render.set_Field(0, "IDS");
         //   render.set_Field(1,"patno");
          //  render.FieldDelimiter = "|";
            render.DefaultSymbol = (ISymbol)simpleFillsymbol;
            render.UseDefaultSymbol = false;

            //颜色
            IRgbColor rgcolor = new RgbColorClass();  //颜色填充
            IRgbColor rgcolor1 = new RgbColorClass();  //图案颜色

            //得到区数
            int regcount = featureClass.FeatureCount(queryfileter);
            //MessageBox.Show(regcount + "区数。");

            //渲染字段
            ESRI.ArcGIS.Geodatabase.IFields fields = new FieldsClass();
            int idfield = 0;
            int regcolorfield = 0;
            int regpatnofield = 0;
            int regpatnocolorfield = 0;

            fields = featurecursor.Fields;
            idfield = fields.FindField("IDS");
            regcolorfield = fields.FindField("fillcolor");
            regpatnofield = fields.FindField("patid");
            regpatnocolorfield = fields.FindField("patcolor");

            //遍历记录
            IFeatureBuffer featurebuff = featureClass.CreateFeatureBuffer();
            for (int i = 0; i < regcount;i++ )
            {
                //下移遍历整个dbf
                featurebuff = (IFeatureBuffer)featurecursor.NextFeature();
                
                //获取各字段值
                string id = (string)featurebuff.get_Value(idfield);
                int fillcolor = (int)featurebuff.get_Value(regcolorfield);
                int patno = (int)featurebuff.get_Value(regpatnofield);
                int patnocolor = (int)featurebuff.get_Value(regpatnocolorfield);
                
                //将获取的颜色号转为rgb
                /************************************************************************/
                IXMapColorLib clib = new mcMapColorLibClass();
                if (fillcolor == 0)
                {
                    fillcolor = 1;
                }
                mcMapColor col = clib.get_MapColor(fillcolor);
                mcColorRGB rgb = col.RGBValue;
                /************************************************************************/
                //将颜色值赋给简单填充的颜色对象
                rgcolor = new RgbColorClass();
                rgcolor.Red = rgb.Red;
                rgcolor.Green = rgb.Green;
                rgcolor.Blue = rgb.Blue;

                rgcolor1 = new RgbColorClass();
                //MessageBox.Show("dbf字段："+id + "" + fillcolor + "  " + patno + "  " + patnocolor);

                fillsymbol = new SimpleFillSymbolClass();
                simpleFillsymbol = new SimpleFillSymbolClass();

                if (patno == 0)
                {
                    //颜色渲染
                     simpleFillsymbol.Color = rgcolor;
                     
                     render.AddValue(id, fillname, (ISymbol)simpleFillsymbol);
                     render.set_Label(id, id);
                     render.set_Symbol(id, (ISymbol)simpleFillsymbol);  
                }
                else
                {
                    //style渲染
                    //加载指定的symbol    style文件  名称格式化
                    string stylename = "R-" + String.Format("{0:0000}", patno);

                    //创建symbol
                    ISymbol symbol = new MultiLayerFillSymbolClass();
                    bool flagexist = false;  

                    symbol = mStyleSymbolMap.GetFillSymbol(stylename);

                    flagexist = (symbol != null);

                    //图案存在
                    if (flagexist)
                    {
                        //图案的颜色
                        IXMapColorLib clib1 = new mcMapColorLibClass();
                        if (patnocolor == 0)
                        {
                            patnocolor = 1;
                        }
                        mcMapColor col1 = clib1.get_MapColor(patnocolor);
                        mcColorRGB rgb1 = col1.RGBValue;
                        rgcolor1.Red = rgb1.Red;
                        rgcolor1.Green = rgb1.Green;
                        rgcolor1.Blue = rgb1.Blue;

                        IMultiLayerFillSymbol pmultilayerfillsymbol = (IMultiLayerFillSymbol)symbol;
                        simpleFillsymbol.Color = rgcolor;
                        pmultilayerfillsymbol.AddLayer(simpleFillsymbol);
                        pmultilayerfillsymbol.MoveLayer(simpleFillsymbol, 1);
                        pmultilayerfillsymbol.Color = rgcolor1;

                        //WriteLogFile(id +"   "+ patno);

                        render.AddValue(id, fillname, (ISymbol)pmultilayerfillsymbol);
                        render.set_Label(id, id);
                        render.set_Symbol(id, (ISymbol)pmultilayerfillsymbol);
                    }
                    else
                    {
                        Logfile.WriteLogFile("区图案不存在：" + stylename);
                    }
                }
            }
            ilayer.Visible = true;
            IGeoFeatureLayer igeofeature = (IGeoFeatureLayer)ilayer;
            IFeatureRenderer featurerender = (IFeatureRenderer)render;
            igeofeature.Name = strName;
            igeofeature.Renderer = featurerender;
            igeofeature.DisplayField = fillname ;

            layerfile.ReplaceContents(igeofeature);
            layerfile.Save();

            layerfile.Close();
        }   
    }
}
